<?php
// +----------------------------------------------------------------------
// | NewThink [ Think More,Think Better! ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2018 http://www.newthink.cc All rights reserved.
// +----------------------------------------------------------------------
// | 版权所有：山西创泰网络科技有限公司
// +----------------------------------------------------------------------
// | Author: JiYun Date:2018-09-20 Time:8:57
// +----------------------------------------------------------------------

/**
 * Class Rsa
 *  注意：需要开启 open_ssl 扩展
 */
class Rsa
{
    /**
     * getKeys()    获取密钥对
     * encrypt()    对数据加密
     * decrypt()    对数据解密
     */
    
    public $config = array(
        // apache 中 openssl 的配置文件
        'config'            =>  'C:\wamp\bin\apache\apache2.4.9\conf\openssl.cnf',
        'digest_alg'        =>  'sha512',
        'private_key_bits'  =>  1024,                //字节数 512 1024 2048 4096 等
        'private_key_type'  =>  OPENSSL_KEYTYPE_RSA, //加密类型
    );
    
    /**
     * 功能：获取密钥对
     *  publibKey   公钥，发送给 APP 端，在 APP 提交关键数据时进行加密使用
     *  privateKey  私钥，保存在 后台端，在 APP 提交的加密数据时进行解密使用
     * @return array
     */
    public function getKeys() {
        $privateKey = '';
        $publicKey  = '';
        
        //创建公钥和私钥   返回资源
        $res = openssl_pkey_new($this->config);
        //从得到的资源中获取私钥，把私钥赋给$privateKey
        openssl_pkey_export($res, $privateKey, null, $this->config);
        //从得到的资源中获取公钥，返回公钥$publicKey
        $publicKey = openssl_pkey_get_details($res);
        $publicKey = $publicKey["key"];
        
        return array('publicKey'=>$publicKey, 'privateKey'=>$privateKey);
    }
    
    /**
     * 功能：用于数据的加密
     *
     * @param $data     待加密的数据
     * @param $publKey  公钥
     * @return string
     */
    public function encrypt($data, $publKey) {
        $crypted = '';
        $data = json_encode($data);
        openssl_public_encrypt($data, $crypted, $publKey);
        return base64_encode($crypted);
    }
    
    /**
     * @param $data     待解密的数据
     * @param $privKey  私钥
     * @return string
     */
    public function decrypt($data, $privKey) {
        $decrypted = '';
        openssl_private_decrypt(base64_decode($data), $decrypted, $privKey);
        return $decrypted;
    }
}

/**
 *  以下是测试方法
 */
function RsaUnit() {
    $rsa = new Rsa();
    // 获取密钥对
    $arr = $rsa->getKeys();

    // 原始数据
    $data = [
        'username' => 'haha',
        'cardno'   => '12345678901',
        'mobile'   => '15011112222',
        '性别'     => '男'
    ];
    
    $e = $rsa->encrypt($data, $arr['publicKey']);
    $d = $rsa->decrypt($e, $arr['privateKey']);
    /**
     * var_dump($arr);
     *  输出密钥对
     * array(2) {
     *  'publicKey' =>
     *      string(272) "-----BEGIN PUBLIC KEY-----
     *      MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDA/lYkadGhLmajKNTE+zNhvPkT
     *      XGXWK5nGmDTYYknBAn2AkjjfasQ3VZq6Cg3K7f+tNUESCJYYpNw7P2t4PsrRaxa5
     *      TJEwmj/o786R0J8R3Vykpwa4Tfd7R4oZtsRbpTgEte5AzPDf4VJSBezzEJDRvLpc
     *      BhOUu9eTyu7+wVy/YwIDAQAB
     *      -----END PUBLIC KEY-----
     *  "
     *  'privateKey' =>
     *      string(916) "-----BEGIN PRIVATE KEY-----
     *      MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMD+ViRp0aEuZqMo
     *      1MT7M2G8+RNcZdYrmcaYNNhiScECfYCSON9qxDdVmroKDcrt/601QRIIlhik3Ds/
     *      a3g+ytFrFrlMkTCaP+jvzpHQnxHdXKSnBrhN93tHihm2xFulOAS17kDM8N/hUlIF
     *      7PMQkNG8ulwGE5S715PK7v7BXL9jAgMBAAECgYAqqg8xDZOiJjfaafRfd4jsWnJV
     *      rV918T2VgaBtFY1odbx459payaeG9A24gvB5pBOZnuQ7sFo+KHPnRSXk9zyum9iQ
     *      GdHmzcWfxvs81GW51uuzbkLHzidVPU6UgIVIAxVRinapJJxdjqLvbzlXDmUP58Yo
     *      UdARC5biBp7iqFUXQQJBAP+mnjU4lovCMRKmEC1gJa7DHMuJPti8hxB6aH0XCOpD
     *      pJRC4GLLorvR47aRgwmUVG2CaATJD"
     *  }
     */
    var_dump($arr);
    /**
     * var_dump($arr);
     *  输出待加密数据的原始信息
     *
     * array(4) {
     *  'username' =>
     *      string(4) "haha"
     *  'cardno' =>
     *      string(11) "12345678901"
     *  'mobile' =>
     *      string(11) "15011112222"
     *  '性别' =>
     *      string(3) "男"
     * }
     */
    var_dump($data);
    /**
     * var_dump($e);
     *  输出加密后的数据
     * string(172) "UUvGzuzPH5B++UVf6SaH4zZ/i6cRhmQcmYMQ1UpfPVjdYOIkLWA2hNtkAGjbYVRDrfWDTy6GEcVEb+16PFe+//NJL4NOyoruqz+4MbUh1F6vcBRA5gxUJTx2w7KieuMxSRm0OzK5u3yEUBMr57lP8LhLNIIu210qt+ixdyKBm4U="
     */
    var_dump($e);
    /**
     * var_dump($d);
     *  输出解密后的数据
     * string(89) "{"username":"haha","cardno":"12345678901","mobile":"15011112222","\u6027\u522b":"\u7537"}"
     */
    var_dump($d);
}

// RsaUnit();